package com.micro.service.routeLocator;

import com.micro.service.dao.RouteRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.util.StringUtils;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 自定义动态路由规则
 */
public class CustomRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {

    @Autowired
    private RouteRepository routeRepository;

    private ZuulProperties properties;

    public CustomRouteLocator(String servletPath, ZuulProperties properties) {
        super(servletPath, properties);
        this.properties = properties;
    }

    @Override
    public void refresh() {
        doRefresh();
    }

    /**
     * 重写实现自定义路由
     *
     * @return
     */
    @Override
    protected Map<String, ZuulProperties.ZuulRoute> locateRoutes() {
        LinkedHashMap<String, ZuulProperties.ZuulRoute> routesMap = new LinkedHashMap<>();
        routesMap.putAll(super.locateRoutes());  //读配置
        routesMap.putAll(getLocateRoutesFromDB()); //读DB
        LinkedHashMap<String, ZuulProperties.ZuulRoute> routes = new LinkedHashMap<>();
        routesMap.forEach((path, route) -> {
            if (!path.startsWith("/")) path = "/" + path;
            if (StringUtils.hasText(this.properties.getPrefix())) {
                path = this.properties.getPrefix() + path;
                if (!path.startsWith("/")) path = "/" + path;
            }
            routes.put(path, route);
        });
        return routes;
    }

    private Map<String, ZuulProperties.ZuulRoute> getLocateRoutesFromDB() {
        Map<String, ZuulProperties.ZuulRoute> routes = new LinkedHashMap<>();
        List<ZuulProperties.ZuulRoute> result = routeRepository.findAll();
        for (ZuulProperties.ZuulRoute route : result) {
            if (StringUtils.isEmpty(route.getPath()) ||
                    (StringUtils.isEmpty(route.getServiceId()) && StringUtils.isEmpty(route.getUrl())))
                continue;
            routes.put(route.getPath(), route);
        }
        return routes;
    }


}
